import os.path
import re

from matplotlib import pyplot as plt


class Pattern:
    @staticmethod
    def load_pattern_file(file_name: str):
        pt = re.compile(r'\((-*\d+),(-*\d+)\)')

        def parse_polygon(polygon_line: str):
            matches = pt.findall(polygon_line)
            current_polygon = []
            for match in matches:
                x, y = map(int, match)
                current_polygon.append((x, y))
            return current_polygon

        def parse_line(file_line: str):
            file_line = file_line.strip()
            if file_line is None or file_line == "" or file_line[0] == "#":
                return "REM", None
            if file_line.find("marker") == 0:
                return "MARKER", None
            if file_line.find("pattern") == 0:
                return "PATTERN", None
            if file_line[0] == "[":
                return "VARIABLE", parse_polygon(file_line)
            if file_line[0] == "(":
                return "BOX", parse_polygon(file_line)

        state = "PATTERN"
        ret = Pattern(file_name)
        with open(file_name, 'r') as file:
            for line in file:
                line_type, line_content = parse_line(line)
                if line_type == "BOX":
                    if state == "MARKER":
                        ret._set_marker(line_content)
                    elif state == "PATTERN":
                        ret._add_polygon(line_content)
                elif line_type == "VARIABLE":
                    ret._add_polygon(line_content, _variable=True)
                elif line_type == "MARKER":
                    state = "MARKER"
                elif line_type == "PATTERN":
                    state = "PATTERN"

        return ret

    def __init__(self, _filename):
        self._marker = None
        self._polygons = []
        self._shadow = []
        self._l, self._r, self._t, self._b = 0x7fffffff, -0x7fffffff, -0x7fffffff, 0x7fffffff
        self._w, self._h = None, None
        self._filename = os.path.split(_filename)[1]

    def _set_marker(self, _vs):
        self._marker = _vs
        for ll in _vs:
            if ll[0] < self._l:
                self._l = ll[0]
            if ll[0] > self._r:
                self._r = ll[0]
            if ll[1] < self._b:
                self._b = ll[1]
            if ll[1] > self._t:
                self._t = ll[1]
        self._w = self._r - self._l
        self._h = self._t - self._b

    def _add_polygon(self, _vs, _variable=False):
        if _variable:
            self._shadow.append(_vs)
        else:
            self._polygons.append(_vs)

    def draw(self):
        fig, ax = plt.subplots()
        polygon = plt.Polygon(self._marker, fill=False, edgecolor="orange")
        ax.add_patch(polygon)
        for vs in self._shadow:
            polygon = plt.Polygon(vs, fill=True, facecolor="lightcoral")
            ax.add_patch(polygon)
        for vs in self._polygons:
            polygon = plt.Polygon(vs, fill=True, facecolor="dodgerblue")
            ax.add_patch(polygon)
        ax.set_xlim(self._l - 0.1 * min(self._w, self._h), self._r + 0.1 * min(self._w, self._h))
        ax.set_ylim(self._b - 0.1 * min(self._w, self._h), self._t + 0.1 * min(self._w, self._h))
        ax.set_aspect('equal')
        plt.title(self._filename)
        plt.show()
